package view;

import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;

public class CalculatorView extends JFrame {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	// button labels, grids, widths held in arrays
	private JButton[] buttons = new JButton[19];
	private String[] buttonLabels = { "0", "1", "2", "3", "4", "5", "6", "7",
			"8", "9", "000", ".", "C", "CE", "+", "-", "*", "/", "=" };
	private int[] buttonGridX = { 0, 0, 1, 2, 0, 1, 2, 0, 1, 2, 1, 2, 4, 5, 4,
			5, 4, 5, 4 };
	private int[] buttonGridY = { 4, 3, 3, 3, 2, 2, 2, 1, 1, 1, 4, 4, 1, 1, 2,
			2, 3, 3, 4 };
	private int[] buttonWidth = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
			1, 1, 1, 2 };

	private int buttonCIndex = 12;
	private int buttonCEIndex = 13;
	private int buttonEnterIndex = 18;
	// 0,1,..,9,dot,000, +,-,*,/
	private int[] mathButtonIndexes = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
			14, 15, 16, 17 };

	private JTextField textInput, textResult;
	private JLabel labelEq = new JLabel("=");

	JPanel mainPanel = new JPanel();

	public static void main(String[] args) {
		new CalculatorView();
	}

	public CalculatorView() {

		try {
			for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
				if ("Nimbus".equals(info.getName())) {
					UIManager.setLookAndFeel(info.getClassName());
					break;
				}
			}
		} catch (Exception e) {
			// If Nimbus is not available, you can set the GUI to another look
			// and feel.
		}

		this.setSize(400, 250);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setTitle("Xalculator");

		mainPanel.setLayout(new GridBagLayout());
		GridBagConstraints gridConstraints = new GridBagConstraints();
		gridConstraints.gridx = 0;
		gridConstraints.gridy = 0;
		gridConstraints.gridwidth = 1; // how many columns
		gridConstraints.gridheight = 1; // how many rows
		gridConstraints.weightx = 10;
		gridConstraints.weighty = 10;

		gridConstraints.insets = new Insets(5, 5, 5, 5);
		gridConstraints.anchor = GridBagConstraints.CENTER;
		gridConstraints.fill = GridBagConstraints.BOTH;

		gridConstraints.gridx = 0;
		gridConstraints.gridy = 0;
		gridConstraints.gridwidth = 3;

		textInput = new JTextField("", 20);
		Font font = new Font("Calibri", Font.ITALIC, 18);
		textInput.setFont(font);
		textInput.setEditable(false);
		mainPanel.add(textInput, gridConstraints);

		ListenForKey lForKey = new ListenForKey();
		textInput.addKeyListener(lForKey);

		gridConstraints.gridx = 3;
		gridConstraints.gridy = 0;
		gridConstraints.gridwidth = 1;
		labelEq.setFont(font);
		mainPanel.add(labelEq, gridConstraints);

		gridConstraints.gridx = 4;
		gridConstraints.gridy = 0;
		gridConstraints.gridwidth = 2;

		textResult = new JTextField("", 15);
		textResult.setFont(font);
		textResult.setEditable(false);
		mainPanel.add(textResult, gridConstraints);

		ListenForButton lForButton = new ListenForButton();

		for (int i = 0; i < buttons.length; i++) {
			gridConstraints.gridx = buttonGridX[i];
			gridConstraints.gridy = buttonGridY[i];
			gridConstraints.gridwidth = buttonWidth[i];
			buttons[i] = new JButton(buttonLabels[i]);
			buttons[i].addActionListener(lForButton);
			mainPanel.add(buttons[i], gridConstraints);
		}

		this.add(mainPanel);
		this.setVisible(true);
		this.setResizable(false);
		//this.pack();

	}

	private void calculateResult() {
		textResult.setText(CalculatorParser.performOperation(CalculatorParser
				.parseInput(textInput.getText())));
		textInput.requestFocusInWindow();
	}

	private class ListenForButton implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {

			for (int i : mathButtonIndexes) {
				if (e.getSource() == buttons[i]) {
					if (textResult.getText().length() > 0) {
						textResult.setText("");
						textInput.setText(CalculatorParser.parseOnTheGo("",
								buttons[i].getText()));
						textInput.requestFocusInWindow();
					} else {
						textInput.setText(CalculatorParser.parseOnTheGo(
								textInput.getText(), buttons[i].getText()));
						textInput.requestFocusInWindow();
					}
				}
			}

			if (e.getSource() == buttons[buttonCEIndex]) {
				textInput.setText("");
				textResult.setText("");
				textInput.requestFocusInWindow();
			} else if (e.getSource() == buttons[buttonCIndex]) {
				String text = textInput.getText();
				if (text.length() > 0) {
					text = text.substring(0, text.length() - 1);
					textInput.setText(text);
					textInput.requestFocusInWindow();
				}
			} else if (e.getSource() == buttons[buttonEnterIndex]) {
				calculateResult();
			}

		}

	}

	private class ListenForKey implements KeyListener {

		@Override
		public void keyTyped(KeyEvent e) {
		}

		@Override
		public void keyPressed(KeyEvent e) {
			String keyStr = Character.toString(e.getKeyChar());
			keyStr=keyStr.replace(",",".");
			
			if (keyStr.equals("\n")) {
				calculateResult();
			} else {
				if (textResult.getText().length() > 0) {
					textResult.setText("");
					textInput
							.setText(CalculatorParser.parseOnTheGo("", keyStr));
				} else {
					textInput.setText(CalculatorParser.parseOnTheGo(
							textInput.getText(), keyStr));
				}
			}
		}

		@Override
		public void keyReleased(KeyEvent e) {
		}

	}

}
